using System;
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Expression.Extensions.Utils;

namespace NHibernate.Expression.Extensions {
    public static class NHibernateUtilEx {
        public static bool IsInitialized(Expression<Func<object>> e) {
            foreach (var o in e.MemberPath()) {
                if (o.Key == null)
                    break;
                if (!NHibernateUtil.IsInitialized(o.Value.GetValue(o.Key)))
                    return false;
            }
            return true;
        }

        public static bool IsInitializedAndAccessible(Expression<Func<object>> e) {
            var visitor = new MemberPathExpressionVisitor(e);
            var memberAccess = visitor.MemberAccesses.ToList();
            for (var i = 0; i < memberAccess.Count; i++) {
                var o = memberAccess[i];
                var kv = MemberPathExpressionVisitor.MemberExpToObj(o);
                if (kv.Key == null)
                    return i == memberAccess.Count;
                var value = kv.Value.GetValue(kv.Key);
                if (!NHibernateUtil.IsInitialized(value))
                    return false;
            }
            return true;
        }

        public static bool IsInitializedAndNotNull(Expression<Func<object>> e) {
            var visitor = new MemberPathExpressionVisitor(e);
            var memberAccess = visitor.MemberAccesses.ToList();
            for (var i = 0; i < memberAccess.Count; i++) {
                var o = memberAccess[i];
                var kv = MemberPathExpressionVisitor.MemberExpToObj(o);
                if (kv.Key == null)
                    return false;
                var value = kv.Value.GetValue(kv.Key);
                if (!NHibernateUtil.IsInitialized(value) || value == null)
                    return false;
            }
            return true;
        }
    }
}